package zelix.hack.hacks;

import net.minecraft.block.*;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.client.multiplayer.WorldClient;
import net.minecraft.client.settings.KeyBinding;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumActionResult;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.*;
import net.minecraftforge.client.event.EntityViewRenderEvent.CameraSetup;
import net.minecraftforge.client.event.RenderWorldLastEvent;
import net.minecraftforge.fml.common.gameevent.TickEvent.ClientTickEvent;
import net.minecraftforge.fml.relauncher.ReflectionHelper;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import zelix.hack.Hack;
import zelix.hack.HackCategory;
import zelix.managers.HackManager;
import zelix.utils.*;
import zelix.utils.hooks.visual.RenderUtils;
import zelix.value.Mode;
import zelix.value.ModeValue;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;

public class Scaffold extends Hack {

	public ModeValue mode;

	public TimerUtils timer;
	public BlockData blockData;
	boolean isBridging = false;
	BlockPos blockDown = null;
	public static float[] facingCam = null;
	float startYaw = 0;
	float startPitch = 0;

	public Scaffold() {
		super("Scaffold", HackCategory.PLAYER);

		this.mode = new ModeValue("Mode", new Mode("AAC", false), new Mode("Simple", true), new Mode("GodBridge", false));

		this.addValue(mode);

		this.timer = new TimerUtils();
	}

	@Override
	public String getDescription() {
		return "Automatically places blocks below your feet.";
	}

	@Override
	public void onDisable() {
		HackManager.getHack("SafeWalk").setToggled(false);
		facingCam = null;
		super.onDisable();
	}

	@Override
	public void onEnable() {
		blockDown = null;
		facingCam = null;
		isBridging = false;
		startYaw = 0;
		startPitch = 0;
		if (mode.getMode("AAC").isToggled() && Wrapper.INSTANCE.mcSettings().keyBindBack.isKeyDown()) {
			KeyBinding.setKeyBindState(Wrapper.INSTANCE.mcSettings().keyBindBack.getKeyCode(), false);
		}
		HackManager.getHack("SafeWalk").setToggled(true);

		super.onEnable();
	}

	@Override
	public void onClientTick(ClientTickEvent event) {
		if (mode.getMode("AAC").isToggled()) {
			AAC();
			godBridgeTimer = 0;
		} else if (mode.getMode("Simple").isToggled()) {
			Simple();
			godBridgeTimer = 0;
		} else if (mode.getMode("GodBridge").isToggled()) {
			GodBridge();
		}
		super.onClientTick(event);
	}
	 
	@Override
	public void onRenderWorldLast(RenderWorldLastEvent event) {
		if (blockDown != null) {
			RenderUtils.drawBlockESP(blockDown, 1F, 1F, 1F);
			if (mode.getMode("AAC").isToggled()) {
				BlockPos blockDown2 = new BlockPos(Wrapper.INSTANCE.player()).down();
				BlockPos blockDown3 = new BlockPos(Wrapper.INSTANCE.player()).down();
				if (Wrapper.INSTANCE.player().getHorizontalFacing() == EnumFacing.EAST) {
					blockDown2 = new BlockPos(Wrapper.INSTANCE.player()).down().west();
					blockDown3 = new BlockPos(Wrapper.INSTANCE.player()).down().west(2);
				} else if (Wrapper.INSTANCE.player().getHorizontalFacing() == EnumFacing.NORTH) {
					blockDown2 = new BlockPos(Wrapper.INSTANCE.player()).down().south();
					blockDown3 = new BlockPos(Wrapper.INSTANCE.player()).down().south(2);
				} else if (Wrapper.INSTANCE.player().getHorizontalFacing() == EnumFacing.SOUTH) {
					blockDown2 = new BlockPos(Wrapper.INSTANCE.player()).down().north();
					blockDown3 = new BlockPos(Wrapper.INSTANCE.player()).down().north(2);
				} else if (Wrapper.INSTANCE.player().getHorizontalFacing() == EnumFacing.WEST) {
					blockDown2 = new BlockPos(Wrapper.INSTANCE.player()).down().east();
					blockDown3 = new BlockPos(Wrapper.INSTANCE.player()).down().east(2);
				}
				RenderUtils.drawBlockESP(blockDown2, 1F, 0F, 0F);
				RenderUtils.drawBlockESP(blockDown3, 1F, 0F, 0F);
			}
		}
		super.onRenderWorldLast(event);
	}

	@SideOnly(Side.CLIENT)
	@Override
	public void onCameraSetup(CameraSetup event) {
		if (mode.getMode("AAC").isToggled() && event.getEntity() == Wrapper.INSTANCE.player()) {
			if (startYaw == 0 || startPitch == 0) {
				return;
			}
			event.setYaw(startYaw);
			event.setPitch(startPitch - 70);
			facingCam = new float[] { startYaw - 180, startPitch - 70 };
		}
		super.onCameraSetup(event);
	}
	
	public int godBridgeTimer;
	void GodBridge() {
		if (godBridgeTimer > 0) {
			/*
			 * ReflectionHelper.setPrivateValue(Minecraft.class, mc, new Integer(0), new
			 * String[] { "rightClickDelayTimer", "field_71467_ac" });
			 */
			godBridgeTimer--;
		}

		if (Wrapper.INSTANCE.world() == null || Wrapper.INSTANCE.player() == null)
			return;
		WorldClient world = Wrapper.INSTANCE.world();
		EntityPlayerSP player = Wrapper.INSTANCE.player();
		RayTraceResult movingObjectPosition = player.rayTrace(Wrapper.INSTANCE.controller().getBlockReachDistance(), 1);
		boolean isKeyUseDown = false;
		int keyCode = Wrapper.INSTANCE.mcSettings().keyBindUseItem.getKeyCode();
		if (keyCode >= 0) {
			isKeyUseDown = Keyboard.isKeyDown(keyCode);
		} else {
			isKeyUseDown = Mouse.isButtonDown(keyCode + 100);
		}
		if (movingObjectPosition != null
				&& movingObjectPosition.typeOfHit == RayTraceResult.Type.BLOCK
				&& movingObjectPosition.sideHit == EnumFacing.UP && isKeyUseDown) {

			ItemStack itemstack = player.inventory.getCurrentItem();
			int i = itemstack != null ? itemstack.getMaxStackSize() : 0;

			if (itemstack != null && itemstack.getItem() instanceof ItemBlock) {
				ItemBlock itemblock = (ItemBlock) itemstack.getItem();

				if (!itemblock.canPlaceBlockOnSide((net.minecraft.world.World) world,
						movingObjectPosition.getBlockPos(), movingObjectPosition.sideHit, (EntityPlayer) player,
						itemstack)) {
					BlockPos blockPos = movingObjectPosition.getBlockPos();
					IBlockState blockState = world.getBlockState(blockPos);
					AxisAlignedBB axisalignedbb = blockState.getBlock().getSelectedBoundingBox(BlockUtils.getState(blockPos),world, blockPos);

					if (axisalignedbb == null || world.isAirBlock(blockPos))
						return;

					double x1, x2, y1, y2, z1, z2;
					Vec3d targetVec3 = null;
					Vec3d eyeVec3 = player.getPositionEyes((float) 1);
					x1 = axisalignedbb.minX;
					x2 = axisalignedbb.maxX;
					y1 = axisalignedbb.minY;
					y2 = axisalignedbb.maxY;
					z1 = axisalignedbb.minZ;
					z2 = axisalignedbb.maxZ;

					class Data implements Comparable<Data> {
						public BlockPos blockPos;
						public EnumFacing enumFacing;
						public double cost;

						public Data(BlockPos blockPos, EnumFacing enumFacing, double cost) {
							this.blockPos = blockPos;
							this.enumFacing = enumFacing;
							this.cost = cost;
						}

						@Override
						public int compareTo(Data data) {
							return (this.cost - data.cost) > 0 ? -1 : (this.cost - data.cost) < 0 ? 1 : 0;
						}

					}

					List<Data> list = new ArrayList<Data>();

					if (x1 <= eyeVec3.x && eyeVec3.x <= x2 && y1 <= eyeVec3.y && eyeVec3.y <= y2
							&& z1 <= eyeVec3.z && eyeVec3.z <= z2) {
						// targetVec3 = new Vec3(0.5*(axisalignedbb.minX+axisalignedbb.maxX),
						// 0.5*(axisalignedbb.minY+axisalignedbb.maxY),
						// 0.5*(axisalignedbb.minZ+axisalignedbb.maxZ));
					} else {
						double xCost = Math.abs(eyeVec3.x - 0.5 * (axisalignedbb.minX + axisalignedbb.maxX));
						double yCost = Math.abs(eyeVec3.y - 0.5 * (axisalignedbb.minY + axisalignedbb.maxY));
						double zCost = Math.abs(eyeVec3.z - 0.5 * (axisalignedbb.minZ + axisalignedbb.maxZ));
						double sumCost = xCost + yCost + zCost;
						if (eyeVec3.x < x1) {
							list.add(new Data(blockPos.west(), EnumFacing.WEST, xCost));
						} else if (eyeVec3.x > x2) {
							list.add(new Data(blockPos.east(), EnumFacing.EAST, xCost));
						}

//						if ( eyeVec3.y < y1 ) {
//							list.add(new Data( blockPos.down(), EnumFacing.UP, yCost));
//						} else if ( eyeVec3.y > y2 ) {
//							list.add(new Data( blockPos.up(), EnumFacing.DOWN, yCost ));
//						}

						if (eyeVec3.z < z1) {
							list.add(new Data(blockPos.north(), EnumFacing.NORTH, zCost));
						} else if (eyeVec3.z > z2) {
							list.add(new Data(blockPos.south(), EnumFacing.SOUTH, zCost));
						}

						Collections.sort(list);
						double border = 0.05;
						double x = MathHelper.clamp(eyeVec3.x, x1 + border, x2 - border);
						double y = MathHelper.clamp(eyeVec3.y, y1 + border, y2 - border);
						double z = MathHelper.clamp(eyeVec3.z, z1 + border, z2 - border);
						for (Data data : list) {
							if (!world.isAirBlock(data.blockPos))
								continue;
							if (data.enumFacing == EnumFacing.WEST || data.enumFacing == EnumFacing.EAST) {
								x = MathHelper.clamp(eyeVec3.x, x1, x2);
							} else if (data.enumFacing == EnumFacing.UP || data.enumFacing == EnumFacing.DOWN) {
								y = MathHelper.clamp(eyeVec3.y, y1, y2);
							} else {
								z = MathHelper.clamp(eyeVec3.z, z1, z2);
							}
							targetVec3 = new Vec3d(x, y, z);
							break;
						}

						if (targetVec3 != null) {
//							log("eee");

							double d0 = targetVec3.x - eyeVec3.x;
							double d1 = targetVec3.y - eyeVec3.y;
							double d2 = targetVec3.z - eyeVec3.z;

							// targetVec3 = new Vec3(x,y,z);

							double d3 = MathHelper.sqrt(d0 * d0 + d2 * d2);
							float f = (float) (MathHelper.atan2(d2, d0) * 180.0D / Math.PI) - 90.0F;
							float f1 = (float) (-(MathHelper.atan2(d1, d3) * 180.0D / Math.PI));
							// player.setPositionAndRotation(player.posX, player.posY, player.posZ, f, f1);
							float f2, f3;
							f2 = player.rotationYaw;
							f3 = player.rotationPitch;

							player.rotationYaw = f;
							player.rotationPitch = f1;

//							Vec3 vec31 = player.getLook(1);
//							Vec3 vec32 = vec31.addVector(vec31.x * Wrapper.INSTANCE.controller().getBlockReachDistance(), vec31.y * Wrapper.INSTANCE.controller().getBlockReachDistance(), vec31.z * Wrapper.INSTANCE.controller().getBlockReachDistance());
							RayTraceResult movingObjectPosition1 = player.rayTrace(Wrapper.INSTANCE.controller().getBlockReachDistance(), 1);
//

//							Vec3 lookVec3= player.getLook((float) partialTicks);
//							double reach = 6.0d;
//							Vec3 rayVec3 = eyeVec3.addVector(lookVec3.x * reach, lookVec3.y * reach, lookVec3.z * reach);
//							MovingObjectPosition movingObjectPosition = axisalignedbb.calculateIntercept(eyeVec3, rayVec3);
							// if (movingObjectPosition != null)
							// log(movingObjectPosition.toString());

//							log(movingObjectPosition1.toString());
//							log(blockPos.toString());
							if (movingObjectPosition1.typeOfHit == RayTraceResult.Type.BLOCK
									&& movingObjectPosition1.getBlockPos().getX() == blockPos.getX()
									&& movingObjectPosition1.getBlockPos().getY() == blockPos.getY()
									&& movingObjectPosition1.getBlockPos().getZ() == blockPos.getZ()) {
//							if (movingObjectPosition1.typeOfHit == MovingObjectType.BLOCK ) {
//								log("eee");
//								Wrapper.INSTANCE.mc().getConnection().sendPacket(new C03PacketPlayer.C05PacketPlayerLook(player.rotationYaw, player.rotationPitch, player.onGround));
//								Wrapper.INSTANCE.mc().getConnection().sendPacket(new C03PacketPlayer.C05PacketPlayerLook(player.rotationYaw, player.rotationPitch, player.onGround));
								if (Wrapper.INSTANCE.controller().processRightClickBlock(player, Wrapper.INSTANCE.world(),  blockPos, movingObjectPosition1.sideHit,movingObjectPosition1.hitVec,EnumHand.MAIN_HAND) == EnumActionResult.SUCCESS){
									player.swingArm(EnumHand.MAIN_HAND);
								}
								if (itemstack == null) {
									;
								} else if (itemstack.getMaxStackSize() == 0) {
									player.inventory.mainInventory.set(player.inventory.currentItem,null);
								} else if (itemstack.getMaxStackSize() != i || Wrapper.INSTANCE.controller().isInCreativeMode()) {
									Wrapper.INSTANCE.mc().entityRenderer.itemRenderer.resetEquippedProgress(EnumHand.MAIN_HAND);
								}
							}
							//
							player.rotationYaw = f2;
							player.rotationPitch = f3;
							double pitchDelta = 2.5;
							double targetPitch = 75.5;
							if (targetPitch - pitchDelta < player.rotationPitch
									&& player.rotationPitch < targetPitch + pitchDelta) {
								double mod = player.rotationYaw % 45.0;
								if (mod < 0) {
									mod += 45.0;
								}
//	                	        log(String.format("yaw: %s", mod));
//	                	        log(String.format("Pitch: %s", player.rotationPitch));
								double delta = 5.0;

								if (mod < delta) {
									player.rotationYaw -= mod;
									player.rotationPitch = (float) targetPitch;
//	    							player.prevRotationYaw = player.rotationYaw;
//	    							player.prevRotationPitch = player.rotationPitch;
								} else if (45.0 - mod < delta) {
									player.rotationYaw += 45.0 - mod;
									player.rotationPitch = (float) targetPitch;
//	    							player.prevRotationYaw = player.rotationYaw;
//	    							player.prevRotationPitch = player.rotationPitch;
								}

								// if (Math.abs(rawMod))
							}

							ReflectionHelper.setPrivateValue(Minecraft.class, Wrapper.INSTANCE.mc(), new Integer(1),
									new String[] { "rightClickDelayTimer", "field_71467_ac" });
							godBridgeTimer = 10;

						}

//						log(String.format("x: %s, y: %s, z: %s", x,y,z));

					}
				}
			}

		}
	}
	
	void AAC() {
		EntityPlayerSP player = Wrapper.INSTANCE.player();
		int oldSlot = -1;
		if (!check()) {
			if (isBridging) {
				KeyBinding.setKeyBindState(Wrapper.INSTANCE.mcSettings().keyBindSneak.getKeyCode(),
						BlockUtils.isBlockMaterial(new BlockPos(player).down(), Blocks.AIR));
				isBridging = false;
				if (oldSlot != -1) {
					player.inventory.currentItem = oldSlot;
				}
			}
			startYaw = 0;
			startPitch = 0;
			facingCam = null;
			blockDown = null;
			return;
		}
		startYaw = Wrapper.INSTANCE.player().rotationYaw;
		startPitch = Wrapper.INSTANCE.player().rotationPitch;
		KeyBinding.setKeyBindState(Wrapper.INSTANCE.mcSettings().keyBindRight.getKeyCode(), false);
		KeyBinding.setKeyBindState(Wrapper.INSTANCE.mcSettings().keyBindLeft.getKeyCode(), false);
		blockDown = new BlockPos(player).down();
		float r1 = new Random().nextFloat();
		if (r1 == 1.0f)
			r1--;
		int newSlot = findSlotWithBlock();
		if (newSlot == -1)
			return;
		oldSlot = player.inventory.currentItem;
		player.inventory.currentItem = newSlot;
		player.rotationPitch = Utils.updateRotation(player.rotationPitch, (82.0f - r1), 15.0f);
		int currentCPS = Utils.random(3, 4);
		if (timer.isDelay(1000 / currentCPS)) {
			RobotUtils.clickMouse(1);
			Utils.swingMainHand();
			timer.setLastMS();
		}
		isBridging = true;
		KeyBinding.setKeyBindState(Wrapper.INSTANCE.mcSettings().keyBindSneak.getKeyCode(),
				BlockUtils.isBlockMaterial(new BlockPos(player).down(), Blocks.AIR));
	}

	void Simple() {
		blockDown = new BlockPos(Wrapper.INSTANCE.player()).down();
		if (!BlockUtils.getBlock(blockDown).getMaterial(BlockUtils.getBlock(blockDown).getDefaultState())
				.isReplaceable())
			return;
		int newSlot = findSlotWithBlock();
		if (newSlot == -1)
			return;
		final int oldSlot = Wrapper.INSTANCE.inventory().currentItem;
		Wrapper.INSTANCE.inventory().currentItem = newSlot;
		Utils.placeBlockScaffold(blockDown);
		
		Wrapper.INSTANCE.inventory().currentItem = oldSlot;
	}

	public int findSlotWithBlock() {
		for (int i = 0; i < 9; ++i) {
			final ItemStack stack = Wrapper.INSTANCE.inventory().getStackInSlot(i);
			if (stack != null && stack.getItem() instanceof ItemBlock) {
				Block block = Block.getBlockFromItem(stack.getItem()).getDefaultState().getBlock();
				if (block.isFullBlock(BlockUtils.getBlock(blockDown).getDefaultState()) && block != Blocks.SAND
						&& block != Blocks.GRAVEL) {
					return i;
				}
			}
		}
		return -1;
	}

	boolean check() {
		RayTraceResult object = Wrapper.INSTANCE.mc().objectMouseOver;
		EntityPlayerSP player = Wrapper.INSTANCE.player();
		ItemStack stack = player.inventory.getCurrentItem();
		if (object == null || stack == null) {
			return false;
		}
		if (object.typeOfHit != RayTraceResult.Type.BLOCK) {
			return false;
		}
		if (player.rotationPitch <= 70 || !player.onGround || player.isOnLadder() || player.isInLava()
				|| player.isInWater()) {
			return false;
		}
		if (!Wrapper.INSTANCE.mcSettings().keyBindBack.isKeyDown()) {
			return false;
		}
		return true;
	}

	private boolean isPosSolid(BlockPos pos) {
		Block block = Wrapper.INSTANCE.world().getBlockState(pos).getBlock();

		if ((block.getMaterial(null).isSolid() || !block.isTranslucent(null) || block.isFullCube(null)
				|| block instanceof BlockLadder || block instanceof BlockCarpet || block instanceof BlockSnow
				|| block instanceof BlockSkull) && !block.getMaterial(null).isLiquid()
				&& !(block instanceof BlockContainer)) {
			return true;
		}

		return false;
	}

	private BlockData getBlockData(BlockPos pos) {
		if (isPosSolid(pos.add(0, -1, 0))) {
			return new BlockData(pos.add(0, -1, 0), EnumFacing.UP);
		}

		if (isPosSolid(pos.add(-1, 0, 0))) {
			return new BlockData(pos.add(-1, 0, 0), EnumFacing.EAST);
		}

		if (isPosSolid(pos.add(1, 0, 0))) {
			return new BlockData(pos.add(1, 0, 0), EnumFacing.WEST);
		}

		if (isPosSolid(pos.add(0, 0, 1))) {
			return new BlockData(pos.add(0, 0, 1), EnumFacing.NORTH);
		}

		if (isPosSolid(pos.add(0, 0, -1))) {
			return new BlockData(pos.add(0, 0, -1), EnumFacing.SOUTH);
		}

		BlockPos pos1 = pos.add(-1, 0, 0);

		if (isPosSolid(pos1.add(0, -1, 0))) {
			return new BlockData(pos1.add(0, -1, 0), EnumFacing.UP);
		}

		if (isPosSolid(pos1.add(-1, 0, 0))) {
			return new BlockData(pos1.add(-1, 0, 0), EnumFacing.EAST);
		}

		if (isPosSolid(pos1.add(1, 0, 0))) {
			return new BlockData(pos1.add(1, 0, 0), EnumFacing.WEST);
		}

		if (isPosSolid(pos1.add(0, 0, 1))) {
			return new BlockData(pos1.add(0, 0, 1), EnumFacing.NORTH);
		}

		if (isPosSolid(pos1.add(0, 0, -1))) {
			return new BlockData(pos1.add(0, 0, -1), EnumFacing.SOUTH);
		}

		BlockPos pos2 = pos.add(1, 0, 0);

		if (isPosSolid(pos2.add(0, -1, 0))) {
			return new BlockData(pos2.add(0, -1, 0), EnumFacing.UP);
		}

		if (isPosSolid(pos2.add(-1, 0, 0))) {
			return new BlockData(pos2.add(-1, 0, 0), EnumFacing.EAST);
		}

		if (isPosSolid(pos2.add(1, 0, 0))) {
			return new BlockData(pos2.add(1, 0, 0), EnumFacing.WEST);
		}

		if (isPosSolid(pos2.add(0, 0, 1))) {
			return new BlockData(pos2.add(0, 0, 1), EnumFacing.NORTH);
		}

		if (isPosSolid(pos2.add(0, 0, -1))) {
			return new BlockData(pos2.add(0, 0, -1), EnumFacing.SOUTH);
		}

		BlockPos pos3 = pos.add(0, 0, 1);

		if (isPosSolid(pos3.add(0, -1, 0))) {
			return new BlockData(pos3.add(0, -1, 0), EnumFacing.UP);
		}

		if (isPosSolid(pos3.add(-1, 0, 0))) {
			return new BlockData(pos3.add(-1, 0, 0), EnumFacing.EAST);
		}

		if (isPosSolid(pos3.add(1, 0, 0))) {
			return new BlockData(pos3.add(1, 0, 0), EnumFacing.WEST);
		}

		if (isPosSolid(pos3.add(0, 0, 1))) {
			return new BlockData(pos3.add(0, 0, 1), EnumFacing.NORTH);
		}

		if (isPosSolid(pos3.add(0, 0, -1))) {
			return new BlockData(pos3.add(0, 0, -1), EnumFacing.SOUTH);
		}

		BlockPos pos4 = pos.add(0, 0, -1);

		if (isPosSolid(pos4.add(0, -1, 0))) {
			return new BlockData(pos4.add(0, -1, 0), EnumFacing.UP);
		}

		if (isPosSolid(pos4.add(-1, 0, 0))) {
			return new BlockData(pos4.add(-1, 0, 0), EnumFacing.EAST);
		}

		if (isPosSolid(pos4.add(1, 0, 0))) {
			return new BlockData(pos4.add(1, 0, 0), EnumFacing.WEST);
		}

		if (isPosSolid(pos4.add(0, 0, 1))) {
			return new BlockData(pos4.add(0, 0, 1), EnumFacing.NORTH);
		}

		if (isPosSolid(pos4.add(0, 0, -1))) {
			return new BlockData(pos4.add(0, 0, -1), EnumFacing.SOUTH);
		}

		BlockPos pos19 = pos.add(-2, 0, 0);

		if (isPosSolid(pos1.add(0, -1, 0))) {
			return new BlockData(pos1.add(0, -1, 0), EnumFacing.UP);
		}

		if (isPosSolid(pos1.add(-1, 0, 0))) {
			return new BlockData(pos1.add(-1, 0, 0), EnumFacing.EAST);
		}

		if (isPosSolid(pos1.add(1, 0, 0))) {
			return new BlockData(pos1.add(1, 0, 0), EnumFacing.WEST);
		}

		if (isPosSolid(pos1.add(0, 0, 1))) {
			return new BlockData(pos1.add(0, 0, 1), EnumFacing.NORTH);
		}

		if (isPosSolid(pos1.add(0, 0, -1))) {
			return new BlockData(pos1.add(0, 0, -1), EnumFacing.SOUTH);
		}

		BlockPos pos29 = pos.add(2, 0, 0);

		if (isPosSolid(pos2.add(0, -1, 0))) {
			return new BlockData(pos2.add(0, -1, 0), EnumFacing.UP);
		}

		if (isPosSolid(pos2.add(-1, 0, 0))) {
			return new BlockData(pos2.add(-1, 0, 0), EnumFacing.EAST);
		}

		if (isPosSolid(pos2.add(1, 0, 0))) {
			return new BlockData(pos2.add(1, 0, 0), EnumFacing.WEST);
		}

		if (isPosSolid(pos2.add(0, 0, 1))) {
			return new BlockData(pos2.add(0, 0, 1), EnumFacing.NORTH);
		}

		if (isPosSolid(pos2.add(0, 0, -1))) {
			return new BlockData(pos2.add(0, 0, -1), EnumFacing.SOUTH);
		}

		BlockPos pos39 = pos.add(0, 0, 2);

		if (isPosSolid(pos3.add(0, -1, 0))) {
			return new BlockData(pos3.add(0, -1, 0), EnumFacing.UP);
		}

		if (isPosSolid(pos3.add(-1, 0, 0))) {
			return new BlockData(pos3.add(-1, 0, 0), EnumFacing.EAST);
		}

		if (isPosSolid(pos3.add(1, 0, 0))) {
			return new BlockData(pos3.add(1, 0, 0), EnumFacing.WEST);
		}

		if (isPosSolid(pos3.add(0, 0, 1))) {
			return new BlockData(pos3.add(0, 0, 1), EnumFacing.NORTH);
		}

		if (isPosSolid(pos3.add(0, 0, -1))) {
			return new BlockData(pos3.add(0, 0, -1), EnumFacing.SOUTH);
		}

		BlockPos pos49 = pos.add(0, 0, -2);

		if (isPosSolid(pos4.add(0, -1, 0))) {
			return new BlockData(pos4.add(0, -1, 0), EnumFacing.UP);
		}

		if (isPosSolid(pos4.add(-1, 0, 0))) {
			return new BlockData(pos4.add(-1, 0, 0), EnumFacing.EAST);
		}

		if (isPosSolid(pos4.add(1, 0, 0))) {
			return new BlockData(pos4.add(1, 0, 0), EnumFacing.WEST);
		}

		if (isPosSolid(pos4.add(0, 0, 1))) {
			return new BlockData(pos4.add(0, 0, 1), EnumFacing.NORTH);
		}

		if (isPosSolid(pos4.add(0, 0, -1))) {
			return new BlockData(pos4.add(0, 0, -1), EnumFacing.SOUTH);
		}

		BlockPos pos5 = pos.add(0, -1, 0);

		if (isPosSolid(pos5.add(0, -1, 0))) {
			return new BlockData(pos5.add(0, -1, 0), EnumFacing.UP);
		}

		if (isPosSolid(pos5.add(-1, 0, 0))) {
			return new BlockData(pos5.add(-1, 0, 0), EnumFacing.EAST);
		}

		if (isPosSolid(pos5.add(1, 0, 0))) {
			return new BlockData(pos5.add(1, 0, 0), EnumFacing.WEST);
		}

		if (isPosSolid(pos5.add(0, 0, 1))) {
			return new BlockData(pos5.add(0, 0, 1), EnumFacing.NORTH);
		}

		if (isPosSolid(pos5.add(0, 0, -1))) {
			return new BlockData(pos5.add(0, 0, -1), EnumFacing.SOUTH);
		}

		BlockPos pos6 = pos5.add(1, 0, 0);

		if (isPosSolid(pos6.add(0, -1, 0))) {
			return new BlockData(pos6.add(0, -1, 0), EnumFacing.UP);
		}

		if (isPosSolid(pos6.add(-1, 0, 0))) {
			return new BlockData(pos6.add(-1, 0, 0), EnumFacing.EAST);
		}

		if (isPosSolid(pos6.add(1, 0, 0))) {
			return new BlockData(pos6.add(1, 0, 0), EnumFacing.WEST);
		}

		if (isPosSolid(pos6.add(0, 0, 1))) {
			return new BlockData(pos6.add(0, 0, 1), EnumFacing.NORTH);
		}

		if (isPosSolid(pos6.add(0, 0, -1))) {
			return new BlockData(pos6.add(0, 0, -1), EnumFacing.SOUTH);
		}

		BlockPos pos7 = pos5.add(-1, 0, 0);

		if (isPosSolid(pos7.add(0, -1, 0))) {
			return new BlockData(pos7.add(0, -1, 0), EnumFacing.UP);
		}

		if (isPosSolid(pos7.add(-1, 0, 0))) {
			return new BlockData(pos7.add(-1, 0, 0), EnumFacing.EAST);
		}

		if (isPosSolid(pos7.add(1, 0, 0))) {
			return new BlockData(pos7.add(1, 0, 0), EnumFacing.WEST);
		}

		if (isPosSolid(pos7.add(0, 0, 1))) {
			return new BlockData(pos7.add(0, 0, 1), EnumFacing.NORTH);
		}

		if (isPosSolid(pos7.add(0, 0, -1))) {
			return new BlockData(pos7.add(0, 0, -1), EnumFacing.SOUTH);
		}

		BlockPos pos8 = pos5.add(0, 0, 1);

		if (isPosSolid(pos8.add(0, -1, 0))) {
			return new BlockData(pos8.add(0, -1, 0), EnumFacing.UP);
		}

		if (isPosSolid(pos8.add(-1, 0, 0))) {
			return new BlockData(pos8.add(-1, 0, 0), EnumFacing.EAST);
		}

		if (isPosSolid(pos8.add(1, 0, 0))) {
			return new BlockData(pos8.add(1, 0, 0), EnumFacing.WEST);
		}

		if (isPosSolid(pos8.add(0, 0, 1))) {
			return new BlockData(pos8.add(0, 0, 1), EnumFacing.NORTH);
		}

		if (isPosSolid(pos8.add(0, 0, -1))) {
			return new BlockData(pos8.add(0, 0, -1), EnumFacing.SOUTH);
		}

		BlockPos pos9 = pos5.add(0, 0, -1);

		if (isPosSolid(pos9.add(0, -1, 0))) {
			return new BlockData(pos9.add(0, -1, 0), EnumFacing.UP);
		}

		if (isPosSolid(pos9.add(-1, 0, 0))) {
			return new BlockData(pos9.add(-1, 0, 0), EnumFacing.EAST);
		}

		if (isPosSolid(pos9.add(1, 0, 0))) {
			return new BlockData(pos9.add(1, 0, 0), EnumFacing.WEST);
		}

		if (isPosSolid(pos9.add(0, 0, 1))) {
			return new BlockData(pos9.add(0, 0, 1), EnumFacing.NORTH);
		}

		if (isPosSolid(pos9.add(0, 0, -1))) {
			return new BlockData(pos9.add(0, 0, -1), EnumFacing.SOUTH);
		}

		return null;
	}
	 public static float[] getRotations(BlockPos block, EnumFacing face)
	    {
	        double x = block.getX() + 0.5 -Wrapper.INSTANCE.player().posX + (double) face.getFrontOffsetX() / 2;
	        double z = block.getZ() + 0.5 -Wrapper.INSTANCE.player().posZ + (double) face.getFrontOffsetZ() / 2;
	        double y = (block.getY() + 0.5);

		/*
		 * if (currentMode.equalsIgnoreCase("Legit")) { double dist =
		 * Wrapper.INSTANCE.mc().player.getDistance(block.getX() + 0.5 + (double) face.getFrontOffsetX()
		 * / 2, block.getY(), block.getZ() + 0.5 + (double) face.getFrontOffsetZ() / 2);
		 * //if(dist > 1.5){ y += 0.5; //x += (double) face.getFrontOffsetX()/8; //z +=
		 * (double) face.getFrontOffsetZ()/8; //} }
		 */

	        double d1 = Wrapper.INSTANCE.player().posY +Wrapper.INSTANCE.player().getEyeHeight() - y;
	        double d3 = MathHelper.sqrt(x * x + z * z);
	        float yaw = (float)(Math.atan2(z, x) * 180.0D / Math.PI) - 90.0F;
	        float pitch = (float)(Math.atan2(d1, d3) * 180.0D / Math.PI);

	        if (yaw < 0.0F)
	        {
	            yaw += 360f;
	        }

	        return new float[] {yaw, pitch};
	    }
	  private class BlockData
	    {
	        public BlockPos position;
	        public EnumFacing face;

	        private BlockData(BlockPos position, EnumFacing face)
	        {
	            this.position = position;
	            this.face = face;
	        }
	    }
}
